package com.triones.yjj.service.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.cmb.constant.CmbDevConfigConstants;
import com.ruoyi.common.cmb.entity.BB1PAYOPOneParam;
import com.ruoyi.common.cmb.entity.BB1PAYOPTwoParam;
import com.ruoyi.common.cmb.utils.CMBSMUtils;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.helper.LoginHelper;
import com.ruoyi.common.utils.DateUtil;
import com.ruoyi.system.mapper.SysUserMapper;
import com.triones.yjj.entity.OrderDO;
import com.triones.yjj.entity.WithdrawalRecordDO;
import com.triones.yjj.entity.bo.WithdrawalListParams;
import com.triones.yjj.entity.bo.WithdrawalRecordBO;
import com.triones.yjj.entity.vo.OrderListVO;
import com.triones.yjj.entity.vo.WithdrawalRecordCustomVO;
import com.triones.yjj.mapper.WithdrawalRecordMapper;
import com.triones.yjj.service.SettledStoreService;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

/**
 * 特约商户 service 业务实现
 *
 * @Author: triones
 */
@Service
@RequiredArgsConstructor
public class SettledStoreServiceImpl implements SettledStoreService {

    private final SysUserMapper sysUserMapper;

    private final WithdrawalRecordMapper withdrawalRecordMapper;

    private final Logger logger = LoggerFactory.getLogger(getClass());

    @Override
    public List<SysUser> sysUserList() {
        return sysUserMapper.selectList(new LambdaQueryWrapper<SysUser>()
            .eq(SysUser::getDelFlag, 0));
    }

    @Override
    public TableDataInfo<WithdrawalRecordCustomVO> withdrawalPageList(WithdrawalListParams params, PageQuery pageQuery) {
        QueryWrapper<Object> wrapper = Wrappers.query();
        wrapper.eq(ObjectUtil.isNotNull(params.getUserId()),"twr.user_id",params.getUserId());
        wrapper.like(ObjectUtil.isNotEmpty(params.getWithdrawalNo()),"twr.withdrawal_no",params.getWithdrawalNo());
        wrapper.eq(ObjectUtil.isNotNull(params.getStatus()),"twr.status",params.getStatus());
        wrapper.and(ObjectUtil.isNotEmpty(params.getKeyword()),
            wq -> wq.like("su.user_name",params.getKeyword()).or()
                .like("su.phonenumber",params.getKeyword()));
        if (params.getCreateTimeRange() != null && params.getCreateTimeRange().size() > 0) {
            wrapper.between("twr.create_time",params.getCreateTimeRange().get(0),params.getCreateTimeRange().get(1));
        }
        if (params.getReachTimeRange() != null && params.getReachTimeRange().size() > 0) {
            wrapper.between("twr.reach_time",params.getReachTimeRange().get(0),params.getReachTimeRange().get(1));
        }
        wrapper.orderByDesc("twr.create_time");
        Page<WithdrawalRecordCustomVO> result = withdrawalRecordMapper.adminWithdrawalPageList(pageQuery.build(),wrapper);
        return TableDataInfo.build(result);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean doneWithdrawal(WithdrawalRecordBO bo) {

        if (bo.getIds().length > 0) {
            for (Long id : bo.getIds()) {
                WithdrawalRecordDO withdrawalRecordDO = withdrawalRecordMapper.selectById(id);
                if (withdrawalRecordDO == null) {
                    throw new SecurityException("提现记录不存在");
                }
                withdrawalRecordDO.setStatus(bo.getStatus());
                if (bo.getStatus() == 5) {
                    /**
                     * 调用招行 -企银支付单笔经办
                     */
                    BB1PAYOPOneParam bb1PAYOPOneParam = new BB1PAYOPOneParam();
                    bb1PAYOPOneParam.setBusMod(CmbDevConfigConstants.BUSMOD);
                    bb1PAYOPOneParam.setBusCod("N02030");
                    BB1PAYOPTwoParam bb1PAYOPTwoParam = new BB1PAYOPTwoParam();
                    bb1PAYOPTwoParam.setDbtAcc(CmbDevConfigConstants.PAYACC);
                    bb1PAYOPTwoParam.setCrtAcc(withdrawalRecordDO.getBankAccount());
                    bb1PAYOPTwoParam.setCrtNam(withdrawalRecordDO.getCardHolding());
                    bb1PAYOPTwoParam.setCcyNbr("10");
                    bb1PAYOPTwoParam.setTrsAmt(Convert.toStr(withdrawalRecordDO.getAmountTotal()));
                    bb1PAYOPTwoParam.setNusAge("商家系统提现");
                    bb1PAYOPTwoParam.setCrtBnk(withdrawalRecordDO.getBankName() + withdrawalRecordDO.getSubbranch());
                    bb1PAYOPTwoParam.setCrtAdr("a");
                    bb1PAYOPTwoParam.setYurRef(withdrawalRecordDO.getWithdrawalNo());
                    try {

                        JSONObject res = CMBSMUtils.bb1payopProd(bb1PAYOPOneParam, bb1PAYOPTwoParam);
                        System.out.println("response = " + res);
                        JSONObject response = res.getJSONObject("response");
                        JSONObject body = response.getJSONObject("body");
                        List bb1payopz1 = body.getObject("bb1payopz1", List.class);
                        Map map = JSONObject.parseObject(Convert.toStr(bb1payopz1.get(0)), Map.class);
                        // 若经办接口返回FIN+F，可以判定为经办失败
                        if ("FIN".equals(Convert.toStr(map.get("reqSts"),"")) && "F".equals(Convert.toStr(map.get("rtnFlg"),""))) {
                            /**
                             * 并退回提现申请的金额
                             */
                            SysUser sysUser = sysUserMapper.selectById(withdrawalRecordDO.getUserId());
                            if (sysUser == null) {
                                throw new SecurityException("未查询到商户信息");
                            }
                            sysUser.setWalletAmount(sysUser.getWalletAmount().add(withdrawalRecordDO.getAmountTotal()));
                            sysUserMapper.updateById(sysUser);
                            withdrawalRecordDO.setRealityAccountTotal(BigDecimal.ZERO);
                            withdrawalRecordDO.setStatus(3);
                            withdrawalRecordDO.setFailRemark(Convert.toStr(map.get("errTxt"),"银行支付失败，请正确的提交银行卡相关信息"));
                        } else {
                            withdrawalRecordDO.setReqNbr(Convert.toStr(map.get("reqNbr"),""));
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                        throw new SecurityException(e.getMessage());
                    }
                    withdrawalRecordMapper.updateById(withdrawalRecordDO);
                } else if (bo.getStatus() == 6) {
                    withdrawalRecordDO.setFailRemark(bo.getFailRemark());
                    withdrawalRecordDO.setCommission(BigDecimal.ZERO);
                    withdrawalRecordDO.setRealityAccountTotal(BigDecimal.ZERO);
                    /**
                     * 并退回提现申请的金额
                     */
                    SysUser sysUser = sysUserMapper.selectById(withdrawalRecordDO.getUserId());
                    if (sysUser == null) {
                        throw new SecurityException("未查询到商户信息");
                    }
                    sysUser.setWalletAmount(sysUser.getWalletAmount().add(withdrawalRecordDO.getAmountTotal()));
                    sysUserMapper.updateById(sysUser);
                    withdrawalRecordMapper.updateById(withdrawalRecordDO);
                }
            }
        }
        return true;
    }

    @Override
    public List<WithdrawalRecordCustomVO> selectExportList(WithdrawalListParams params) {
        QueryWrapper<Object> wrapper = Wrappers.query();
        wrapper.eq(ObjectUtil.isNotNull(params.getUserId()),"twr.user_id",params.getUserId());
        wrapper.like(ObjectUtil.isNotEmpty(params.getWithdrawalNo()),"twr.withdrawal_no",params.getWithdrawalNo());
        wrapper.eq(ObjectUtil.isNotNull(params.getStatus()),"twr.status",params.getStatus());
        if (params.getCreateTimeRange() != null && params.getCreateTimeRange().size() > 0) {
            wrapper.between("twr.create_time",params.getCreateTimeRange().get(0),params.getCreateTimeRange().get(1));
        }
        if (params.getReachTimeRange() != null && params.getReachTimeRange().size() > 0) {
            wrapper.between("twr.reach_time",params.getReachTimeRange().get(0),params.getReachTimeRange().get(1));
        }
        wrapper.orderByDesc("twr.create_time");
        List<WithdrawalRecordCustomVO> list = withdrawalRecordMapper.adminWithdrawalList(wrapper);
        return list;
    }

    /**
     * 定时更新提现记录
     */
    @Scheduled(cron = "0 0/1 * * * ?")
    @Transactional(rollbackFor = Exception.class)
    public void activitySettlement() {
        List<WithdrawalRecordDO> withdrawalRecordDOS = withdrawalRecordMapper.selectList(new LambdaQueryWrapper<WithdrawalRecordDO>().eq(WithdrawalRecordDO::getStatus, 5));
        if (withdrawalRecordDOS.size() > 0) {
            try {
                for (WithdrawalRecordDO withdrawalRecordDO : withdrawalRecordDOS) {
                    JSONObject res = CMBSMUtils.bb1payqrProd(withdrawalRecordDO.getWithdrawalNo());
                    JSONObject response = res.getJSONObject("response");
                    JSONObject body = response.getJSONObject("body");
                    Map head = response.getObject("head", Map.class);
                    if (body != null || !"{}".equals(body)) {
                        List bb1payqrz1 = body.getObject("bb1payqrz1", List.class);
                        if (bb1payqrz1 != null && bb1payqrz1.size() > 0) {
                            Map map = JSONObject.parseObject(Convert.toStr(bb1payqrz1.get(0)), Map.class);
                            if (map != null) {
                                if ("FIN".equals(Convert.toStr(map.get("reqSts"),""))) {
                                    if ("S".equals(Convert.toStr(map.get("rtnFlg"),""))) {
                                        withdrawalRecordDO.setStatus(2);
                                        withdrawalRecordDO.setReachTime(DateUtil.getDateTimeString());
                                        withdrawalRecordDO.setRealityAccountTotal(Convert.toBigDecimal(map.get("trsAmt")));
                                    } else if ("F".equals(Convert.toStr(map.get("rtnFlg"),""))) {
                                        /**
                                         * 并退回提现申请的金额
                                         */
                                        SysUser sysUser = sysUserMapper.selectById(withdrawalRecordDO.getUserId());
                                        if (sysUser == null) {
                                            throw new SecurityException("未查询到商户信息");
                                        }
                                        sysUser.setWalletAmount(sysUser.getWalletAmount().add(withdrawalRecordDO.getAmountTotal()));
                                        sysUserMapper.updateById(sysUser);
                                        withdrawalRecordDO.setRealityAccountTotal(BigDecimal.ZERO);
                                        withdrawalRecordDO.setStatus(3);
                                        withdrawalRecordDO.setFailRemark("企银支付业务查询结果：提现失败");
                                    }
                                    withdrawalRecordMapper.updateById(withdrawalRecordDO);
                                }
                            }
                        } else if (head != null) {
                            if ("SUC0000".equals(Convert.toStr(head.get("resultcode"),""))) {
                                withdrawalRecordDO.setStatus(2);
                                withdrawalRecordDO.setReachTime(DateUtil.getDateTimeString());
                                withdrawalRecordDO.setRealityAccountTotal(withdrawalRecordDO.getAmountTotal());
                            } else {
                                /**
                                 * 并退回提现申请的金额
                                 */
                                SysUser sysUser = sysUserMapper.selectById(withdrawalRecordDO.getUserId());
                                if (sysUser == null) {
                                    throw new SecurityException("未查询到商户信息");
                                }
                                sysUser.setWalletAmount(sysUser.getWalletAmount().add(withdrawalRecordDO.getAmountTotal()));
                                sysUserMapper.updateById(sysUser);
                                withdrawalRecordDO.setRealityAccountTotal(BigDecimal.ZERO);
                                withdrawalRecordDO.setStatus(3);
                                withdrawalRecordDO.setFailRemark("企银支付业务查询结果：提现失败");
                            }
                            withdrawalRecordMapper.updateById(withdrawalRecordDO);
                        }
                    } else if (head != null) {
                        if ("SUC0000".equals(Convert.toStr(head.get("resultcode"),""))) {
                            withdrawalRecordDO.setStatus(2);
                            withdrawalRecordDO.setReachTime(DateUtil.getDateTimeString());
                            withdrawalRecordDO.setRealityAccountTotal(withdrawalRecordDO.getAmountTotal());
                        } else {
                            /**
                             * 并退回提现申请的金额
                             */
                            SysUser sysUser = sysUserMapper.selectById(withdrawalRecordDO.getUserId());
                            if (sysUser == null) {
                                throw new SecurityException("未查询到商户信息");
                            }
                            sysUser.setWalletAmount(sysUser.getWalletAmount().add(withdrawalRecordDO.getAmountTotal()));
                            sysUserMapper.updateById(sysUser);
                            withdrawalRecordDO.setRealityAccountTotal(BigDecimal.ZERO);
                            withdrawalRecordDO.setStatus(3);
                            withdrawalRecordDO.setFailRemark("企银支付业务查询结果：提现失败");
                        }
                        withdrawalRecordMapper.updateById(withdrawalRecordDO);
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
                throw new SecurityException(e.getMessage());
            }
        }
    }

//    /**
//     * 定时更新提现记录
//     */
//    @Scheduled(cron = "0 0/2 * * * ?")
//    @Transactional(rollbackFor = Exception.class)
//    public void test() throws Exception {
//        JSONObject object = CMBSMUtils.bb1payqr();
//        logger.info("定时更新提现记录 object：" + object);
//    }

}
